package com.irdstudio.apicenter.gateway.core.token;

import java.io.IOException;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.apicenter.gateway.core.weixin.WeiXinUtil;

/**
 * 用于生成JWT会话令牌
 * @author fmf
 *
 */
public class JsonWebTokenUtil {
	/* 文本日志记录对象(Logback对象) */
	private final static Logger logger = LoggerFactory
			.getLogger(JsonWebTokenUtil.class);
    /**
     * 获取token
     * @param Payload JWT的载荷,JSON格式
     * @return 返回token
     */
    public String getToken(JSONObject Payload){
    	//1.对Payload进行base64编码
    	String PayloadBase64=this.getBase64Encoder(Payload);
    	//2.生成Payload的签名
    	String key = WeiXinUtil.getWXProp("KEY_MAC_SECRET");
    	String signature=HmacUtil.encryptHMAC(PayloadBase64,key);
    	//3.对Payload.签名在进行base64编码
    	String str=PayloadBase64+"."+signature;
    	String token=this.getBase64Encoder(str);
		return token;
    }
    /**
     * 校验token的信息是否被篡改，是否已经失效，token有效返回Payload的json数据
     * @param token 令牌
     * @return json
     * @throws IOException 
     */
    public JSONObject checkToken(String token) throws Exception{
    	//1.对token解码
    	String str=this.getBase64DecoderStr(token);
    	//2.取出Payload进行重新签名,比较两次签名
    	String[] strArr=str.split("\\.");
    	if(strArr.length != 2){
    		logger.error("token被篡改");
    		//定义错误码9011
    		throw new Exception("9011");
    	}
    	//token中的载体
    	String PayloadBase64=strArr[0];
    	//token中的签名
    	String oldSignature=strArr[1];
    	//对token的载体，配合密钥重新签名
    	String key = WeiXinUtil.getWXProp("KEY_MAC_SECRET");
    	String newSignature=HmacUtil.encryptHMAC(PayloadBase64,key);
    	//比较两次签名，不一致则token非法
    	if(!oldSignature.equals(newSignature)){
    		logger.error("token被篡改");
    		//定义错误码9011
    		throw new Exception("9011");
    	}
    	//3.解析载体，得到json对象
    	JSONObject json = this.getBase64DecoderJson(PayloadBase64);
    	//4.检查token是否超时
		return json;
    }
	/**
     * 返回经过base64编码的字符串
     * @param json 参数为json
     * @return
     */
    public String getBase64Encoder(JSONObject json){
    	if(json==null){
    		logger.error("编码的字符串为null");
    	}
    	//将JSON转换成JSON字符串
    	String JsonStr=json.toJSONString();
    	String base64Str=Base64.encodeBase64String(JsonStr.getBytes());
		return base64Str;
    }
    /**
     * 返回经过base64编码的字符串
     * @param Str参数为字符串
     * @return
     */
    public String getBase64Encoder(String str){
    	if(str==null){
    		logger.error("编码的字符串为null");
    	}
    	String base64Str=Base64.encodeBase64String(str.getBytes());
		return base64Str;
    }
    
    /**
     * 解base64编码返回JSONObject 
     * @param base64Str
     * @return 返回json
     * @throws IOException 
     */
    public JSONObject getBase64DecoderJson(String base64Str) throws IOException{
		byte[] b=Base64.decodeBase64(base64Str);
		String str=new String(b);
		return JSON.parseObject(str);
    	
    }
    /**
     * 解base64编码返回Str 
     * @param base64Str
     * @return 返回字符串
     * @throws IOException 
     */
    public String getBase64DecoderStr(String base64Str) throws IOException{
		byte[] b=Base64.decodeBase64(base64Str);
		String str=new String(b);
		return str;
    	
    }
    
    
    public static void main(String[] args) {
    	JsonWebTokenUtil a =new JsonWebTokenUtil();
    	JSONObject Payload=new JSONObject();
    	Payload.put("userId","10001");
    	Payload.put("phone","18070908049");
//    	Payload.put("shenfen","100005");
    	Payload.put("time","1409796708679");
    	//json信息编码
    	System.out.println("加密前的json信息:"+Payload);
    	System.out.println("加密前的json信息编码:"+a.getBase64Encoder(Payload));
    	//加密签名返回token
    	String token=a.getToken(Payload);
    	System.out.println("token信息:"+token);
    	//解密
    	try {
    		JSONObject aaajson=a.checkToken(token);
    		System.out.println("解密后的json信息:"+aaajson);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
